package net.ghy;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.bat.db.BaseDAO;
import net.bat.db.BaseDAOImpl;
import net.bat.pt.BObj;
import net.bat.service.IHandle;
import net.bat.util.Cfg;
import net.cs.um.UMService;
import net.ghy.rules.RuleInvoker;
import dao.hb.BxDetailrecord;
import dao.hb.BxMidle;
import dao.hb.BxSimplerecord;
import dao.hb.UUser;
import dao.hb.UserBat;

public class BatBxService  implements IHandle {

	public static final char METHOD_SUBMIT_BXSRECORD = 'S';

	public static final char METHOD_SET_BAOGF = 'B'; // whd

	public static final char METHOD_CONT = 'C';
	
	public static final char METHOD_REVIEW = 'R'; //review 已提交记录核查
	
	public static final char METHOD_CHANGE_STATE_SAVE = 'Z';
	
	public static final char METHOD_GETSIMPLE='G';
	
	public static final char METHOD_GETPREMONEY='M';

	// 数据库操作通用对象
	static private BaseDAO dao;

	public BaseDAO getDao() {
		return dao;
	}

	public void setDao(BaseDAO dao) {
		this.dao = dao;
	}

	public static char getMethodContDataset() {
		return METHOD_CONT;
	}

	static Integer[] getDistinct(Integer num[]) {
		List<Integer> list = new java.util.ArrayList<Integer>();
		for (int i = 0; i < num.length; i++) {
			if (!list.contains(num[i])) {// 如果list数组不包括num[i]中的值的话，就返回true。
				list.add(num[i]); // 在list数组中加入num[i]的值。已经过滤过。
			}
		}
		return list.toArray(new Integer[0]);
	}
    /**   
     * 获取当年第一天日期   
     * @param year 年份   
     * @return Date   
     */    
    public static String getCurrYearFirst(){     
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        calendar.clear();     
        calendar.set(Calendar.YEAR, year);     
        Date currYearFirst = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");      
        return sdf.format(currYearFirst).toString();     
    } 
    public static String getCurrYearFirst(int year){ 
        Calendar calendar = Calendar.getInstance();
        calendar.clear();     
        calendar.set(Calendar.YEAR, year);     
        Date currYearFirst = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");      
        return sdf.format(currYearFirst).toString();     
    } 
    
    /** 
     * 获取某年最后一天日期 
     * @param year 年份 
     * @return Date 
     * @author whd
     */  
    public static String getCurrYearLast(int year){  
    	year=2014;
        Calendar calendar = Calendar.getInstance();  
        calendar.clear();  
        calendar.set(Calendar.YEAR, year);  
        calendar.roll(Calendar.DAY_OF_YEAR, -1);  
        Date currYearLast = calendar.getTime();  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");      
        return sdf.format(currYearLast).toString();  
    }  
    public static int getYear(Date date){
    	 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");     
    	 String ye=sdf.format(date);
         return Integer.parseInt(sdf.format(date).toString());  
    }
	private HashMap<Integer, Double> getBxamount(Integer id, Integer uid, Integer exclude)
			throws Exception {
		HashMap<Integer, Double> bxamount = new HashMap();
		double amount = 0.0;
		if (uid != null && id != null) {
			String hql = " from BxDetailrecord v WHERE v.uid=" + uid
					+ " and v.bxsrPid = " + id;
			if(exclude > 0){
				hql+=" and v.id != "+exclude;
			}
			List ls = dao.find(hql);
			if (ls != null && ls.size() > 0) {
				for (int j = 0; j < ls.size(); j++) {
					BxDetailrecord vc = (BxDetailrecord) ls.get(j);
					amount += vc.getPayOne() + vc.getPayTwo() + vc.getPayAll();
				}
			}
			bxamount.put(uid, amount);
		}
		return (HashMap<Integer, Double>) bxamount;
	}

	private HashMap<Integer, Double> getBaogf(Integer uid) throws Exception {
		HashMap<Integer, Double> bxbaogf = new HashMap();
		Double baogf = 0.0;
		if (uid != null) {
			String hql = " from UUser A  WHERE A.id = " + uid;
			List ls = dao.find(hql);
			UUser user = (UUser) ls.get(0);
			if(user.getWkState().toString().equals("在职")){
				baogf = user.getBaogf();
			}
			    bxbaogf.put(uid, baogf);
		}
		return bxbaogf;
	}
	private boolean bgfCheck(Integer uid,double uamount,Integer exclude) throws Exception{		
		String hql = "from BxSimplerecord A WHERE (A.status is not null and A.status!='未提交') and A.uid = "+ uid;
		if(exclude > 0){
			hql+=" and A.id != "+exclude;
		}
		List ls = dao.find(hql);
		boolean submit = false;
		if(ls!=null &&ls.size()>0){
			submit = true;
		}else {
			HashMap<Integer, Double> baogf = getBaogf(uid);
	    	submit = true ;
	    	if(baogf.get(uid)!=null && uamount < baogf.get(uid)){
	    		submit = false ;						
		}
    }
		return submit;
	}
	private Object[] submitBxsrecord(HashMap<String, Object> req,
			HttpServletRequest request) throws Exception {
		Integer did = (Integer) req.get("id");
		Integer uid =  (Integer) req.get("uid");	
		String hql = " from BxDetailrecord v WHERE v.id=" +did;
		List ls = dao.find(hql);
		Integer srid = ((BxDetailrecord) ls.get(0)).getBxsrPid();
		req.put("id",srid);
		StringBuffer alert = new StringBuffer("当前批次的");	
	    boolean submit = false;	
		HashMap<Integer, Double> amount = getBxamount(srid,uid,0);
		if(amount.get(uid)!=null ){
			    double uamount =amount.get(uid);
				if(uamount==0){
				   alert.append("记录的报销详单总额为0,无法提交!<br>");
				}
				else{
					double money=0.0;
					String d = BXService.getCurrYearFirst();
					java.sql.Date beginDate=java.sql.Date.valueOf(d);
					String bxre = " from BxMidle v WHERE v.uid=" +uid +" and v.bxDate> "+beginDate;
					List bls = dao.find(bxre);				
					if(bls!=null&&bls.size()>0){
						submit =true;
					}else{
						Object[] omoney = calculteBxf(req,request);
						money = (Double)omoney[0];
						if(money>getBaogf(uid).get(uid)){
							submit =true;
						}
					}
					if(!submit)
						alert.append("记录的报销总额为"+money+"，未超过您的包干费"+getBaogf(uid).get(uid)+"，无法提交！<br>");
				}
			if (submit){ 
					String current = "from BxSimplerecord A WHERE A.id = "+ srid;
					List ls_cur = dao.find(current);
					BxSimplerecord bsr = (BxSimplerecord) ls_cur.get(0);
					bsr.setStatus("已提交");
					bsr.setDtSubmit(new Date());
					dao.update(bsr);
					alert.append("记录提交成功。<br>");
				  }
		 }

		return new Object[] { alert.toString() };
	}

	private Object[] contDataSet(HashMap<String, Object> req,
			HttpServletRequest request) throws Exception {
		String hql = (String) req.get("hql");

		int count = dao.getCountByQuery(hql, null);

		return new Object[] { count };

	}

	private Object[] setBaogf(HashMap<String, Object> req,
			HttpServletRequest request) throws Exception {

		BaseDAOImpl bdi = (BaseDAOImpl) Cfg.getBean("BaseDAOImpl");
		String us="from UUser";
		List ul=dao.find(us);
		if(ul.size()>0){
			for(int i=0;i<ul.size();i++){
				UUser uu=(UUser)ul.get(i);
				int uid=uu.getId();
				String ub="from UserBat where uid="+uid;
				List bl=dao.find(ub);
				if(bl.size()==1){
					UserBat bu=(UserBat)bl.get(0);
					bu.setWkState(uu.getWkState());
					bu.setWkYears(uu.getWkYears());
					bu.setBaogf(uu.getBaogf());
					bu.setSubbgfFlag(uu.getSubbgfFlag());
					dao.update(bu);
				}else{
					UserBat cb=new UserBat();
					cb.setUid(uid);
					if(uu.getWkState()!=null)
					cb.setWkState(uu.getWkState());
					if(uu.getWkYears()!=null)
					cb.setWkYears(uu.getWkYears());
					if(uu.getBaogf()!=null)
					cb.setBaogf(uu.getBaogf());
					if(uu.getSubbgfFlag()!=null)
					cb.setSubbgfFlag(uu.getSubbgfFlag());
					dao.save(cb);
				}
			}
		}
		
		String sql = "from  UUser u  where   u.wkState ='在职'";
		Date d = new Date();
		List ls = dao.find(sql);
		if (ls != null && ls.size() > 0)
			for (int j = 0; j < ls.size(); j++) {
				Object os = (Object) ls.get(j);
				UUser usr = (UUser) os;
				if(usr.getWkYears()!=null){
					int wkYears = usr.getWkYears();
					double baogf = 0;
					if (wkYears >= 1 && wkYears <= 5) {
						baogf = 300;
					} else if (wkYears >= 6 && wkYears <= 10) {
						baogf = 400;
					} else if (wkYears >= 11 && wkYears <= 20) {
						baogf = 500;
					} else if (wkYears >= 21 && wkYears <= 30) {
						baogf = 600;
					} else if (wkYears >= 31) {
						baogf = 700;
					}
	                usr.setSubbgfFlag("true");
					usr.setBaogf(baogf);
					usr.setYear(d.getYear()+1900);
					usr.setWkYears(wkYears+1);
					dao.update(usr);
				}
				
			}

		return new Object[] {};
	}

	private Object[] calculteBxf(HashMap<String, Object> req,
			HttpServletRequest request) throws Exception {
		// 1.获得报销简表id
		Double money=0.0;
		Integer bxsrid = 0;
		if (req.get("id") instanceof String) {
			bxsrid = Integer.parseInt((String) req.get("id"));
		}
		if (req.get("id") instanceof Integer) {
			bxsrid = (Integer) req.get("id");
		}
		String status = req.get("status").toString();
		String flg="";
		if(req.get("flg")!=null){
			flg=req.get("flg").toString();
		}
		
		if(bxsrid==0){
			UUser usr = UMService.getUserBySession(request);
			int uid = usr.getId();
			String ql="from BxSimplerecord where (status='已提交' or status='未提交') and uid="+uid;
			BxSimplerecord bxs=(BxSimplerecord)dao.find(ql).get(0);
			bxsrid=bxs.getId();
		}
		
		// 2.

		String hql = "from BxDetailrecord where bxsrPid=" + bxsrid;
		List bxList = dao.find(hql); // 从视图中获得本次报销中所有单据的汇总记录

		// 3.进入规则库计算报销金额
		RuleInvoker ri = new RuleInvoker();
		Map<String, Object> map = new HashMap<String, Object>();
		if (bxList != null && bxList.size() > 0) {
			BxDetailrecord vb = (BxDetailrecord) bxList.get(0);
			Integer uid = vb.getUid();
			String userHql = "from UUser where  id=" + uid;
			//查询此次报销是否是本年度，不是获取上一年用户信息
			
			UUser user = (UUser) dao.find(userHql).get(0);
			Date dt=new Date();
			int year=getYear(dt);
			if(vb.getDtLook()!=null&&(getYear(vb.getDtLook())!=year)){
			String	batHql="from UserBat  where uid="+uid;
			     UserBat ub=(UserBat)dao.find(batHql).get(0);
			     user.setWkState(ub.getWkState());
			     user.setSubbgfFlag(ub.getSubbgfFlag());
			     user.setYear(ub.getYear());
			     user.setWkYears(ub.getWkYears());
			     year=getYear(vb.getDtLook());
			}
		    Double baogf=user.getBaogf();           //获得报销人的包干费
		    String bogFlag=user.getSubbgfFlag();
		    if(baogf==null){
		    	baogf=0.0;
		    }
		    
			// 然后把 UUser 和 BxDetailrecord 存放到map中
			map.put("UUser", user); // 获得报销的用户信息
			map.put("bxList", bxList); // 本次报销明细列表 BxDeatilrecord

			// 存放报销说明
			Map<String, Map<String, String>> rm = new HashMap<String, Map<String, String>>();

		    Map<String,String> wkMap=new HashMap<String,String>();
		    wkMap.put("住院","在职:住院工龄20年以内30万元以下(自付1、自付2)80%,封顶线(30万元)以上(自付1、自付2)90%。工龄21年以上(自付1、自付2)90%;自费:60%(合计不超过3000元/年)<br>");
		    wkMap.put("门诊","在职:门诊工龄20年以内(自付1、自付2)80%,工龄21年以上(自付1、自付2)90%;自费:30%(合计不超过1000/年)<br>");
		    wkMap.put("大病医疗(器械)","在职:大病医疗(器械)自费70%<br>");
		    wkMap.put("大病医疗(药物)","在职:大病医疗(药物)自费60%<br>");
		    wkMap.put("计划生育", "在职:计划生育工龄20年以内100%,工龄21年以上100%<br>");
		    
		    
		    Map<String,String>txMap=new HashMap<String,String>();
		    txMap.put("住院","退休:住院30万元以下(自付1、自付2)100%,封顶线(30万元)以上(自付1、自付2)95%;自费:60%(合计不超过3000元/年)<br>");
		    txMap.put("门诊","退休:门急诊2万元以下(自付1、自付2)100%,封顶线(2万元)以上(自付1、自付2)95%;自费:60%(合计不超过1000元/年)<br>");
		    txMap.put("大病医疗(器械)","退休:大病医疗(器械)自费80%<br>");
		    txMap.put("大病医疗(药物)","退休:大病医疗(药物)自费70%<br>");
		    txMap.put("计划生育", "退休:计划生育100%<br>");

			rm.put("在职", wkMap);
			rm.put("退休", txMap);

			map.put("rm", rm);

			List midList = new ArrayList();
			for (int i = 0; i < bxList.size(); i++) {
				// 创建大小相等的midle对象
				BxMidle bm = new BxMidle();
				midList.add(bm);
			}
			map.put("midList", midList);
			String start=getCurrYearFirst(year);
			String end=getCurrYearLast(year);
			String tql = "from BxMidle where uid=" + uid + " and bxtype='住院 ' and ( dtLook >= '" +start + "' and dtLook <='" + end +"')"; 
			List bxm = dao.find(tql);
			Double tp1 = 0.0;
			if (bxm.size() > 0) {
				for (int i = 0; i < bxm.size(); i++) {
					BxMidle mid = (BxMidle) bxm.get(i);
					tp1 += mid.getPayall();
				}
			}
			String tq2 = "from BxMidle where uid=" + uid+ " and bxtype='门诊 ' and ( dtLook >= '" +start + "' and dtLook <='" + end +"')";  // 最后加当年日期
			List bxm2 = dao.find(tq2);
			Double tp2 = 0.0;
			if (bxm2.size() > 0) {
				for (int i = 0; i < bxm2.size(); i++) {
					BxMidle mid2 = (BxMidle) bxm2.get(i);
					tp2 += mid2.getPayall();
				}
			}

			Map<String, Double> topValue = new HashMap<String, Double>();
			topValue.put("住院", tp1);
			topValue.put("门诊", tp2);
			map.put("topValue", topValue);
			if(flg!=""){
	            map.put("flg",flg);
               
			}
			ri.execRule(map);
			// 规则走完后

			bxList = (List) map.get("bxList");
			midList = (List) map.get("midList");
			
            if(status.equals("3")){
            	if(bxList!=null){
    				Double sum = 0.0;
    		
    				for (int j = 0; j < bxList.size(); j++) {
    					BxMidle mid = (BxMidle) midList.get(j);
    					sum += Math.round(mid.getBxSum()*100);
    				}
    				    money=sum/100.0;
            	}
            }else{
    			if (bxList != null) {
    				String rem = "";
    				String simpRem="";
    				String newRemark="";
    				Double sum = 0.0;
    				int rn = 0;
    				String uql = "from BxMidle where bxSid=" + bxsrid;
    				List libxm = dao.find(uql);
    				if (libxm.size() > 0) {
    					for (int s = 0; s < libxm.size(); s++) {
    						dao.delete((BxMidle) libxm.get(s));
    					}
    				}
    				for (int j = 0; j < bxList.size(); j++) {
    					BxDetailrecord b = (BxDetailrecord) bxList.get(j);
    					if (status.equals("2")) {
    						BxMidle mid = (BxMidle) midList.get(j);
    						mid.setUid(b.getUid());
    						mid.setBxSid(bxsrid);
    						mid.setDid(b.getId());
    						mid.setDtLook(b.getDtLook());
    						mid.setWkState(user.getWkState());
    						mid.setname(user.getName());
    						dao.save(mid);
    					} else {
 
    						b.setPrebxCost(b.getBxCost());
    						b.setPreRemark(b.getRemark());
                            
    						b.setBxCost(0.0);
    						b.setRemark("");
    						

    					}
    					    
                        
    					BxMidle mid = (BxMidle) midList.get(j);
    					rem += "票据编号:"+b.getId()+":"+mid.getRemark();
    					sum += Math.round(mid.getBxSum()*100);
    					
    					simpRem+="["+(j+1)+"]"+b.getRemark()+"<br>";
    					
    					newRemark+="["+(j+1)+"]"+"+";
    					
    					if(status.equals("3")){
    						b.setPrebxCost(0.0);
    						b.setPreRemark("");
    						money=sum/100.0;
    					}
    					    
    					dao.update(bxList.get(j));


    				}
                      sum=sum/100.0;
    				BxDetailrecord bm = (BxDetailrecord) bxList.get(0);

    				Integer sid = bm.getBxsrPid();
    				String shl = "from BxSimplerecord where id=" + sid;
    				BxSimplerecord bs = (BxSimplerecord) dao.find(shl).get(0);
    				if (status.equals("2")) {
    					if(bogFlag!=null&&(bogFlag.equals("true"))){
    						if(sum>baogf){
    							if(flg==""){
    								sum=Math.round(sum*100-baogf*100)/100.0;
    								user.setSubbgfFlag("false");
    								dao.update(user);
    								if(baogf>0.0){
    									rem=rem+"本次减去包干费:"+baogf;
    									newRemark=simpRem+"<br>"+newRemark.substring(newRemark.length()-1)+"-"+baogf+"="+sum;
    								}
    								
    							}
    							bs.setStatus("审核通过");
    							bs.setRemark(rem);
    							bs.setBxSum(sum);
    							bs.setNewRemark(newRemark);
    							bs.setDtCheck(new Date());
    							if(bs.getDtSubmit()==null){
    								bs.setDtSubmit(new Date());
    							}
    							
    						}else{
    							bs.setRemark(rem+"小于包干费不予报销");
    							
    						}
    					
    					}else{
    						String str=newRemark.substring(0,newRemark.length()-1);
    						newRemark=simpRem+"<br>"+newRemark.substring(0,newRemark.length()-1)+"="+sum;
    						bs.setStatus("审核通过");
    						bs.setRemark("根据"+year+"报销准则:"+rem);
    						bs.setBxSum(sum);
    						bs.setDtCheck(new Date());
    						bs.setNewRemark(newRemark);
    						if(bs.getDtSubmit()==null){
								bs.setDtSubmit(new Date());
							}
    					}
    					
    					
    				} else {
    					if(sum>baogf){
    						sum=(sum*100-baogf*100)/100.0;
    						if(baogf>0.0){
    							rem=rem+"预减去包干费:"+baogf;
    						}
    						bs.setPrebxCost(sum);
    						bs.setPreRemark(rem);
    					}
    					
    				}
    				if(flg!=""){
    		           bs.setDiff("true");
    	               
    				}

    				String cq = "from BxDetailrecord where bxsrPid=" + sid;
    				List li = dao.find(cq);
    				bs.setReceiptsNum(li.size());
    				dao.update(bs);
    			}
            }
		


		}
		return new Object[] {money};
	}

	private Object[] review(HashMap<String, Object> req) throws Exception{
		String hql =(String)req.get("hql");
		List ls = dao.find(hql); 
		BxDetailrecord cbr = (BxDetailrecord) ls.get(0);
		int uid = cbr.getUid();
		int bxsrPid = cbr.getBxsrPid();
		BObj[] objs = (BObj[])req.get("objs");
		HashMap<String,Object> data = objs[0].getItems();
		if(data.get("id")!=null){  //只针对修改记录 新增不判断
		int id = (Integer) data.get("id");
		HashMap<Integer, Double> uamount = getBxamount(bxsrPid,uid,id);
		double amount = uamount.get(uid);
		String alert = "";
		boolean save = true;
		if(data.containsKey("payOne")||data.containsKey("payTwo")||data.containsKey("payAll")){
			if(data.containsKey("payOne")){
				amount += Double.parseDouble((String) data.get("payOne"));
			}if(data.containsKey("payTwo")){
				amount +=  Double.parseDouble((String) data.get("payTwo"));
			}if(data.containsKey("payAll")){
				amount += Double.parseDouble((String) data.get("payAll"));
			}			
			save = bgfCheck(uid,amount,bxsrPid);
			if(save){
				return new Object[] {};
			}else {
				return new Object[] {save};
			}
			
		}else{
			return  new Object[] {};
		}		
		}else{
			
			//dao.save(bd);	
			return  new Object[] {};
		}
	
	}
	private Object[] cssave(HashMap<String, Object> req){
		String hql =(String)req.get("hql");
		List ls = dao.find(hql); 
		BxDetailrecord cbr = (BxDetailrecord) ls.get(0);
		int uid = cbr.getUid();
		int bxsrPid = cbr.getBxsrPid();
		String shql = "from BxSimplerecord A WHERE A.id = "+ bxsrPid;
		List sls = dao.find(shql); 
		BxSimplerecord sbr = (BxSimplerecord) sls.get(0);
		sbr.setStatus("未提交");
		sbr.setDtModify(new Date());
		dao.update(sbr);
		return  new Object[] {};
		
	}
	@Override
	public Object handle(char method, HashMap<String, Object> rm,
			HttpServletRequest request) throws Exception {

		switch (method) {
		case METHOD_SUBMIT_BXSRECORD:
			return submitBxsrecord(rm, request);
		case METHOD_SET_BAOGF:
			return setBaogf(rm, request);
		case METHOD_CONT:
			return calculteBxf(rm, request);
		case METHOD_REVIEW:
			return review(rm);
		case METHOD_CHANGE_STATE_SAVE:
			return cssave(rm);
		case METHOD_GETSIMPLE:
			return getSimple(rm);
		case METHOD_GETPREMONEY:
			return getMoney(rm);
		}
		return null;
	}

	private Object getMoney(HashMap<String, Object> rm) {
		  
		  
		return null;
	}

	private Object getSimple(HashMap<String, Object> req) {
		String hql=(String)req.get("hql");
		List li=dao.find(hql);
		
		if(li.size()>0){
			BxSimplerecord bs=(BxSimplerecord)li.get(0);
			return bs;
		}
		
		return new Object[]{};
	}

}

